package chaoyue.study.safe;

import chaoyue.study.ThreadUtils;

/**
 * wait和notify都是作用在monitor之上的
 * 非常适合用来实现生产者-消费者模型
 */
public class WaitNotifyTest {
    private static int num = 10;
    private static int count = 0;
    private static final Object MONITOR = new Object();

    public static void main(String[] args) {
        // 消费者线程
        Thread consumerThread = new Thread(() -> {
            while (true) {
                ThreadUtils.sleep(1000);
                minus();
            }
        });

        // 生产者线程
        Thread producerThread = new Thread(() -> {
            while (true) {
                ThreadUtils.sleep(2000);
                plus();
            }
        });

        consumerThread.start();
        producerThread.start();
    }

    public static void minus() {
        synchronized (MONITOR) {
            if (num <= 0) {
                try {
                    // 如果num不足，则当前线程基于MONITOR阻塞，等待生产者生产
                    MONITOR.wait();
                } catch (InterruptedException ignored) {
                }
            }
            num--;
            System.out.println("消费者消费 剩余: " + num);
        }
    }

    public static void plus() {
        synchronized (MONITOR) {
            if (num >= 10) {
                // 如果num超过10个，唤醒wait在MONITOR对象上的线程执行（注意：当前线程并不会阻塞）
                MONITOR.notify();
            }
            num++;
            count++;
            System.out.println("生产者生产 剩余: " + num + " 总共生产: " + count);
        }
    }
}
